package com.lin.knife4j;

import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.OAuthBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;

/**
 * @作者: 林江
 * @创建时间: 2024/2/24
 * @功能: swagger的配置工厂
 */
public class SwaggerConfigFactory {

    SwaggerProperties swaggerProperties;

    public SwaggerConfigFactory(SwaggerProperties swaggerProperties) {
        this.swaggerProperties = swaggerProperties;
    }

    public Docket groupRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(groupApiInfo())
                .groupName(swaggerProperties.getGroupName())
                .select()
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
                .paths(PathSelectors.any())
                .build()
                // 权限登录拦截
                // 1. 哪些路径是需要进行有权访问的。
                .securityContexts(CollectionUtils.newArrayList(securityContext()))
                // 2.knife4j设置登录界面
                .securitySchemes(getSecuritySchemes())
                ;
    }


    private ApiInfo groupApiInfo() {
        return new ApiInfoBuilder().title(swaggerProperties.getApiInfo().getTitle()).description(swaggerProperties.getApiInfo().getDescription()).termsOfServiceUrl(swaggerProperties.getApiInfo().getTermsOfServiceUrl()).contact(swaggerProperties.getApiInfo().getContact()).version(swaggerProperties.getApiInfo().getVersion()).build();
    }

    private SecurityContext securityContext() {
        List<AuthorizationScope> scopes = new ArrayList<>();
        scopes.add(new AuthorizationScope("read", "read  resources"));
        scopes.add(new AuthorizationScope("write", "write resources"));
        scopes.add(new AuthorizationScope("reads", "read all resources"));
        scopes.add(new AuthorizationScope("writes", "write all resources"));
        SecurityReference reference = new SecurityReference("oauth2", scopes.toArray(new AuthorizationScope[]{}));
        return SecurityContext.builder().securityReferences(CollectionUtils.newArrayList(reference)).forPaths(PathSelectors.any()).build();
    }

    private List<? extends SecurityScheme> getSecuritySchemes() {
        //schema
        List<GrantType> grantTypes = new ArrayList<>();
        //密码模式
        String passwordTokenUrl = swaggerProperties.getOauth2Url();
        ResourceOwnerPasswordCredentialsGrant resourceOwnerPasswordCredentialsGrant = new ResourceOwnerPasswordCredentialsGrant(passwordTokenUrl);
        grantTypes.add(resourceOwnerPasswordCredentialsGrant);
        OAuth oAuth = new OAuthBuilder().name("oauth2").grantTypes(grantTypes).build();

        return CollectionUtils.newArrayList(oAuth);
    }

//    private ApiKey apiKey() {
//        return new ApiKey("BearerToken", "Authorization", "header");
//    }
//
//    private SecurityContext securityContext() {
//        return SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.any()).build();
//    }
//
//    List<SecurityReference> defaultAuth() {
//        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
//        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
//        authorizationScopes[0] = authorizationScope;
//        return CollectionUtils.newArrayList(new SecurityReference("BearerToken", authorizationScopes));
//    }
}
